/**
 * 产业洞察地图组件
 * @param city 城市
 * @param data 数据
 * @param seicLv1Code 战兴
 */
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue';
import { mapMap, getLeft, getTop } from '@config/map/InsightMap';
import './style.scss';

export default defineComponent({
  name: 'IndustryMap',
  props: {
    city: String,
    data: Array,
    seicLv1Code: Number,
  },
  setup: (props) => {
    const state: { city: string; cityKey: string; companyList: any; boundary: any } = reactive({
      city: '',
      cityKey: '',
      companyList: [],
      boundary: {}, // 地图的相关配置
      // boundary: {
      //   width: 570,
      //   height: 630,
      //   maxJ: 120.65047,
      //   minJ: 120.52379,
      //   maxW: 31.38105,
      //   minW: 31.25732,
      //   top: 80,
      //   left: 74,
      // },
    });

    const left = (longitude) => {
      if (longitude < state.boundary.minJ || longitude > state.boundary.maxJ) {
        longitude = (state.boundary.maxJ + state.boundary.minJ) / 2;
      }
      return getLeft(state.boundary.width, longitude, state.boundary.maxJ, state.boundary.minJ, state.boundary.left);
    };

    const top = (latitude) => {
      if (latitude < state.boundary.minW || latitude > state.boundary.maxW) {
        latitude = (state.boundary.maxW + state.boundary.minW) / 2;
      }
      return getTop(state.boundary.height, latitude, state.boundary.maxW, state.boundary.minW, state.boundary.top);
    };

    // 计算碰撞体积
    const collisionDetection = () => {
      const list = state.companyList.sort((a, b) => a.top - b.top);
      let x = 0;
      state.companyList = list.map((item: any, index: number) => {
        const top = item.top;
        let txtTop = 0;
        if (!index) {
          return {
            ...item,
            txtTop: 0,
          };
        } else {
          // diff 数组前一位减去当前
          const diff = top - list[index - 1].top; // 数据已排序，diff必为正数
          // 判断是否小于40（交集）
          if (diff < 40) {
            // 公共存储量变更为 （本身 + diff）
            x = x + (40 - diff);
            txtTop = x;
          } else {
            // 不小于 x 就置空（归零）
            x = 0;
            txtTop = 0;
          }
          return {
            ...item,
            txtTop,
          };
        }
      });
    };

    watch(
      () => props.data,
      (e: any) => {
        state.companyList = e?.map((item: any) => {
          return {
            ...item,
            left: left(item.longitude),
            top: top(item.latitude),
          };
        });
        collisionDetection();
      }
    );

    onMounted(() => {
      // 过滤字符串市、区为空
      state.city = props.city || '昆山';
      const city = state.city.replace(/市|区/g, '') || '昆山';
      // 根据传入的城市过滤出他的key
      const mapValue = Object.keys(mapMap)
        .map((item) => ({ label: mapMap[item].label, key: item, boundary: mapMap[item].boundary })) // 循环对象转数组
        .filter((item) => item.label === city)[0]; // 过滤label === city
      state.cityKey = mapValue.key;
      state.boundary = mapValue.boundary;
    });

    return toRefs(state);
  },
  render() {
    return (
      <div id="IndustryMap">
        {this.cityKey && <img src={require(`@assets/industry_map/img_${this.cityKey}.png`)} alt="" />}
        {this.companyList.map((item) => (
          <div
            class="company_name"
            style={{
              top: `${item.top}px`,
              left: `${item.left}px`,
            }}
          >
            <video src={require('@assets/industry_map/ripple.mp4')} autoplay muted loop={true}></video>
            <label
              class={[
                'company_name--txt',
                800 - item.left < (item.company_name.length + 1) * 20 + 60 ? 'txt_right' : 'txt_left', // 计算是否因为宽度不够超出而改变方向
              ]}
              style={{
                top: `${item.txtTop}px`,
                width: `${(item.company_name.length + 1) * 20}px`, // 宽度动态计算
              }}
            >
              {item.company_name}
            </label>
          </div>
        ))}
        <footer>
          <p>{this.city}</p>
        </footer>
      </div>
    );
  },
});
